<template>
  <view>
    <!-- #ifdef MP-WEIXIN -->
    <qmy-custom-navbar :title="'内容编辑'"></qmy-custom-navbar>
    <!-- #endif -->
    <view :style="{marginTop:menuObject.top + menuObject.height + 8 +'px'}" class="editor_toolbox">
      <view style="display: flex;">
        <!-- 翻转180度,左对齐 -->
        <i class="iconfonts iconfont ic-qianjin" style="transform: rotate(180deg);margin-bottom: 4rpx;"
           data-method="undo" @tap="edit" />
        <i class="iconfonts iconfont ic-qianjin" style="margin-top: 2rpx;" data-method="redo" @tap="edit" />
        <i class="iconfonts iconfont ic-tupian01-F" style="font-size: 66rpx;margin-top: 1rpx;"
           data-method="insertImg" @tap="edit" />
        <i class="iconfonts iconfont ic-bofang-fang-F" style="font-size: 68rpx;" data-method="insertVideo"
           @tap="edit" />
        <i class="iconfonts iconfont ic-lianjie-fang-F" style="font-size: 68rpx;" data-method="insertLink"
           @tap="edit" />
        <i class="iconfonts iconfont ic-biaotilan" style="margin-top: 2rpx;font-size: 68rpx;"
           data-method="insertText" @tap="edit" />
        <i class="iconfonts iconfont ic-shanchu2-fang-F" style="font-size: 68rpx;" data-method="insertHtml"
           data-param="<hr style='margin:10px 0'/>" @tap="edit" />
        <i class="iconfonts iconfont ic-h" style="font-size: 60rpx;margin-top: 6rpx;" @tap="insertHead" />
      </view>
      <view style="display: flex;">
        <i class="iconfonts iconfont ic-yinyongfang" style="font-size: 66rpx;" data-method="insertHtml"
           data-param="<blockquote style='padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5'>引用</blockquote>"
           @tap="edit" />
        <i class="iconfonts iconfont ic-secaibiaoge" style="font-size: 67rpx;" @tap="insertTable" />
        <i class="iconfonts iconfont ic-daima1" style="font-size: 60rpx;margin-top: 3rpx;" @tap="insertCode" />
        <i class="iconfonts iconfont ic-weixiaobiaoqing" style="margin-top: -2rpx;" data-type="emoji"
           @tap="openDialog" />
        <i class="iconfonts iconfont ic-mobanzhongxin-copy" style="margin-top: -2rpx;" data-type="template"
           @tap="openDialog" />
        <i class="iconfonts iconfont ic-shanchu" style="font-size: 62rpx;" @tap="clear" />
        <i class="iconfonts iconfont ic-daoru" style="font-size: 61rpx;margin-top: 2rpx;" @tap="load" />
        <i :class="'iconfonts iconfont ic-'+(editable?'baocun-F':'gerenxinxibianji')" style="font-size: 62rpx;"
           @tap="save" />
      </view>
    </view>
    <view>
      <mp-html ref="article"
               :container-style="`padding:20rpx;min-height:calc(100vh - ${menuObject.top + menuObject.height + 130}px);padding-top:30px`"
               :content="content" domain="https://mp-html.oss-cn-hangzhou.aliyuncs.com" :tag-style="tagStyle"
               :editable="editable" @remove="remove" />
    </view>
    <block v-if="modal">
      <view class="mask" />
      <view class="modal">
        <view class="modal_title">{{modal.title}}</view>
        <view class="modal_body">
          <block v-if="modal.title=='插入表格'">
            <picker class="modal_picker" :range="[1,2,3,4,5,6,7,8,9]" data-type="rows"
                    @change="pickerChange">
              {{rows}}
            </picker>行
            <picker class="modal_picker" :range="[1,2,3,4,5]" data-type="cols" @change="pickerChange">
              {{cols}}
            </picker>列
          </block>
          <input v-else class="modal_input" :value="modal.value" maxlength="-1" auto-focus
                 @input="modalInput" />
        </view>
        <view class="modal_foot">
          <view class="modal_button" @tap="modalCancel">取消</view>
          <view class="modal_button" style="color:#576b95;border-left:1px solid rgba(0,0,0,.1)"
                @tap="modalConfirm">确定
          </view>
        </view>
      </view>
    </block>
    <!-- 底部弹窗 -->
    <view class="fadeIn" v-if="dialog">
      <view class="mask" @tap="closeDialog"></view>
      <view class="weui-half-screen-dialog">
        <view class="weui-half-screen-dialog__hd">
          <view class="weui-half-screen-dialog__hd__side" @tap="closeDialog">
            <view class="weui-icon-btn"><i class="weui-icon-close-thin"></i></view>
          </view>
          <view class="weui-half-screen-dialog__hd__main">
            <strong class="weui-half-screen-dialog__title">插入{{dialog=='emoji'?'表情':'模板'}}</strong>
          </view>
        </view>
        <view class="weui-half-screen-dialog__bd"
              :style="'height:'+(dialog=='emoji'?'105':'150')+'px; padding-bottom: 30px;'">
          <view v-if="dialog=='emoji'" v-for="(line, index) in emojis"
                style="display: flex; font-size: 20px; line-height: 35px">
            <view style="flex:1" v-for="(item, index) in line" :data-emoji="item" @tap="insertEmoji">
              {{item}}
            </view>
          </view>
          <view v-if="dialog=='template'" v-for="(item, index) in templates" @tap="closeDialog">
            <rich-text :nodes="item" data-method="insertHtml" :data-param="item" @tap="edit" />
            <view style="border-top:1px dashed gray; width: 80%; height: 0; margin: 20px auto" />
          </view>
        </view>
		</view>
		</view>
	</view>
</template>

<script>
	import mpHtml from '@/components/mp-html/mp-html'
	// 上传图片方法
	function upload(src, type) {
		return new Promise(async (resolve, reject) => {
			console.log('上传', type === 'img' ? '图片' : '视频', '：', src)
			try {
				const { upload: uploadRequest } = require('@/utils/request.js')
				const uploadResult = await uploadRequest('/api/upload/media', {
					file: src
      });
				resolve(uploadResult.data.url)
			} catch (error) {
				reject(error)
			}
		})
  /*
  // 实际使用时，上传到服务器
  wx.uploadFile({
    url: 'xxx', // 接口地址
    filePath: src,
    name: 'xxx',
    success(res) {
      resolve(res.data.path) // 返回线上地址
    },
    fail: reject
  })
  */
}
	// 删除图片方法
	function remove(src) {
		console.log('删除图片：', src)
		// 实际使用时，删除线上资源
	}
	export default {
		data() {
			return {
				// #ifdef MP-WEIXIN

      menuObject: uni.getMenuButtonBoundingClientRect(),

				// #endif

				// #ifndef MP-WEIXIN

      menuObject: 20,

				// #endif
      content: '',
      modal: null,
      dialog: false,
      editable: true,
      // 预设的标签样式
      tagStyle: {
        table: 'box-sizing:border-box;border-top:1px solid #dfe2e5;border-left:1px solid #dfe2e5',
        th: 'border-right:1px solid #dfe2e5;border-bottom:1px solid #dfe2e5',
        td: 'border-right:1px solid #dfe2e5;border-bottom:1px solid #dfe2e5',
        li: 'margin:5px 0'
      },
      rows: 1,
      cols: 1,
      // 用于插入的 emoji 表情
      emojis: [
        ['??', '??', '??', '??', '??', '??', '??', '??', '??'],
        ['??', '??', '??', '??', '??', '??', '??', '??', '??'],
        ['??', '??', '??', '??', '??', '??', '??', '??', '??']
      ],
      // 用于插入的 html 模板
      templates: [
        '<section style="text-align: center; margin: 0px auto;"><section style="border-radius: 4px; border: 1px solid #757576; display: inline-block; padding: 5px 20px;"><span style="font-size: 18px; color: #595959;">标题</span></section></section>',
        '<div style="width: 100%; box-sizing: border-box; border-radius: 5px; background-color: #f6f6f6; padding: 10px; margin: 10px 0"><div>卡片</div><div style="font-size: 12px; color: gray">正文</div></div>',
        '<div style="border: 1px solid gray; box-shadow: 3px 3px 0px #cfcfce; padding: 10px; margin: 10px 0">段落</div>'
      ]
			}
		},
		components: {
			mpHtml
		},
		onLoad(e) {
    if (e.data && e.source == 'notice') {
      console.log(e.data)
      // 处理传递过来的encodeURIComponent(this.content)
      this.content = decodeURIComponent(e.data);
      console.log(this.content)
    }
    // uni.showActionSheet({
    // 	itemList: ['简易模式', '正常模式'],
    // 	success: e => {
    // 		if (e.tapIndex === 0) {
    // 			this._editmode = 'simple'
    // 			this.editable = this._editmode
    // 		} else {
    // 			this._editmode = true
    // 		}
    // 	}
    // })
    this._editmode = true
  },
  onReady() {
    /**
     * @description 设置获取链接的方法
     * @param {String} type 链接的类型（img/video/audio/link）
     * @param {String} value 修改链接时，这里会传入旧值
     * @returns {Promise} 返回线上地址
     *   type 为音视频时可以返回一个数组作为源地址
     *   type 为 audio 时，可以返回一个 object，包含 src、name、author、poster 等字段
     */
    this.$refs.article.getSrc = (type, value) => {
      return new Promise((resolve, reject) => {
        if (type === 'img' || type === 'video') {
          uni.showActionSheet({
            itemList: ['本地选取', '远程链接'],
            success: res => {
              if (res.tapIndex === 0) {
                // 本地选取
                if (type === 'img') {
                  uni.chooseImage({
                    count: value === undefined ? 9 :
                        1, // 2.2.0 版本起插入图片时支持多张（修改图片链接时仅限一张）
                    success: res => {
                      // #ifdef MP-WEIXIN
                      if (res.tempFilePaths.length == 1 && wx
                          .editImage) {
                        // 单张图片时进行编辑
                        wx.editImage({
                          src: res.tempFilePaths[
                              0],
                          complete: res2 => {
                            uni.showLoading({
                              title: '上传中'
                            })
                            upload(res2
                                    .tempFilePath ||
                                res
                                    .tempFilePaths[
                                    0],
                                type)
                                .then(
                                    res => {
                                      uni.hideLoading()
                                      resolve
                                      (
                                          res
                                      )
                                    })
                          }
                        })
                      } else {
                        // #endif
                        uni.showLoading({
                          title: '上传中'
                        });
                        (async () => {
                          const arr = []
                          for (let item of res
                              .tempFilePaths) {
                            // 依次上传
                            const src =
                                await upload(
                                    item, type)
                            arr.push(src)
                          }
                          return arr
                        })().then(res => {
                          uni.hideLoading()
                          resolve(res)
                        })
                        // #ifdef MP-WEIXIN
                      }
                      // #endif
                    },
                    fail: reject
                  })
                } else {
                  uni.chooseVideo({
                    success: res => {
                      uni.showLoading({
                        title: '上传中'
                      })
                      upload(res.tempFilePath, type).then(
                          res => {
                            uni.hideLoading()
                            resolve(res)
                          })
                    },
                    fail: reject
                  })
                }
              } else {
                // 远程链接
                this.callback = {
                  resolve,
                  reject
                }
                this.$set(this, 'modal', {
                  title: (type === 'img' ? '图片' : '视频') + '链接',
                  value
                })
              }
            }
          })
        } else {
          this.callback = {
            resolve,
            reject
          }
          let title
          if (type === 'audio') {
            title = '音频链接'
          } else if (type === 'link') {
            title = '链接地址'
          }
          this.$set(this, 'modal', {
            title,
            value
          })
        }
      })
			}
		},
		methods: {
    // 删除图片/视频/音频标签事件
    remove(e) {
      // 删除线上资源
      remove(e.src)
    },
    // 处理模态框
    modalInput(e) {
      this.value = e.detail.value
    },
    modalConfirm() {
      this.callback.resolve(this.value || this.modal.value || '')
      this.$set(this, 'modal', null)
    },
    modalCancel() {
      this.callback.reject()
      this.$set(this, 'modal', null)
    },
    pickerChange(e) {
      this.$set(this, e.currentTarget.dataset.type, parseInt(e.detail.value) + 1)
    },
    // 处理底部弹窗
    openDialog(e) {
      this.checkEditable().then(() => {
        this.$set(this, 'dialog', e.currentTarget.dataset.type)
      }).catch(() => {})
    },
    closeDialog() {
      this.$set(this, 'dialog', false)
    },
    // 检查是否可编辑
    checkEditable() {
      return new Promise((resolve, reject) => {
        if (this.editable) {
          resolve()
        } else {
          uni.showModal({
            content: '需要继续编辑吗？',
            success: res => {
              if (res.confirm) {
                // 切换编辑状态
                this.save()
                resolve()
              } else {
                reject()
              }
            }
          })
        }
      })
    },
    // 调用编辑器接口
    edit(e) {
      this.checkEditable().then(() => {
        this.$refs.article[e.currentTarget.dataset.method](e.currentTarget.dataset.param)
      })
    },
    // 插入 head 系列标签
    insertHead() {
      this.checkEditable().then(() => {
        uni.showActionSheet({
          itemList: ['大标题', '中标题', '小标题'],
          success: res => {
            let tagName = ['h1', 'h3', 'h5'][res.tapIndex]
            this.$refs.article.insertHtml(`<${tagName}>标题</${tagName}>`)
          }
        })
      }).catch(() => {})
    },
    // 插入表格
    insertTable() {
      this.checkEditable().then(() => {
        this.$set(this, 'modal', {
          title: '插入表格'
        })
        this.callback = {
          resolve: () => {
            this.$refs.article.insertTable(this.rows, this.cols)
          },
          reject: () => {}
        }
      }).catch(() => {})
    },
    // 插入代码
    insertCode() {
      this.checkEditable().then(() => {
        uni.showActionSheet({
          itemList: ['css', 'javascript', 'json'],
          success: res => {
            const lan = ['css', 'javascript', 'json'][res.tapIndex]
            this.$refs.article.insertHtml(
                `<pre><code class="language-${lan}">${lan} code</code></pre>`)
          }
        })
      }).catch(() => {})
    },
    // 插入 emoji
    insertEmoji(e) {
      this.$refs.article.insertHtml(e.currentTarget.dataset.emoji)
      this.closeDialog()
    },
    // 清空编辑器内容
    clear() {
      uni.showModal({
        title: '确认',
        content: '确定清空内容吗？',
        success: res => {
          if (res.confirm)
            this.$refs.article.clear()
        }
      })
    },
    // 加载内容
    load() {
      this.checkEditable().then(() => {
        uni.showModal({
          title: '提示',
          content: '导入内容将覆盖现有内容，是否继续？',
          success: res => {
            if (res.confirm) {
              if (!uni.chooseMessageFile) {
                return uni.showModal({
                  title: '失败',
                  content: '暂时无法使用此功能',
                  showCancel: false
                })
              }
              uni.chooseMessageFile({
                count: 1,
                type: 'file',
                extension: ['txt', 'html'],
                success: res => {
                  const content = uni.getFileSystemManager()
                      .readFileSync(res.tempFiles[0]
                          .path, 'utf8')
                  this.$refs.article.setContent(content)
                }
              })
            }
          }
        })
      }).catch(() => {})
    },
    // 保存编辑器内容
    save() {
      setTimeout(() => {
        if (this.editable) {
          var content = this.$refs.article.getContent()
          this.content = content
          // 结束编辑
          this.$Toast('保存成功')
          this.editable = false
          this.getOpenerEventChannel().emit('refreshData', content)
          setTimeout(() => {
				uni.navigateBack()
          }, 200)
        } else {
          this.editable = this._editmode
        }
      }, 50)
			}
		}
	}
</script>

<style>
page {
  line-height: 1.6;
}

.editor_toolbox {
  width: 100%;
  z-index: 999;
  top: 0;
  background-color: #ffffff;
  padding: 5px;
  box-sizing: border-box;
  border-bottom: 1rpx solid #f3f3f3;
}

.iconfonts {
  flex: 1;
  color: #125045;
  text-align: center;
  font-size: 65rpx;
}


/* 模态框 */
.modal {
  position: fixed;
  top: 50%;
  left: 16px;
  right: 16px;
  background-color: #fff;
  border-radius: 12px;
  transform: translateY(-50%);
  text-align: center;
}

.modal_title {
  padding: 32px 24px 16px;
  font-size: 17px;
  font-weight: 700;
  text-align: center;
}

.modal_body {
  padding: 0 24px;
  margin-bottom: 32px;
  font-size: 17px;
  line-height: 1.4;
  word-wrap: break-word;
  color: rgba(0, 0, 0, .5);
}

.modal_input {
  display: block;
  padding: 5px;
  font-size: 14px;
  border: 1px solid #dfe2e5;
}

.modal_picker {
  display: inline-block;
  margin: 0 5px;
  border-bottom: 1px solid gray;
  padding: 0 5px;
}

.modal_foot {
  display: flex;
  line-height: 56px;
  font-weight: 700;
  border-top: 1px solid rgba(0, 0, 0, .1);
}

.modal_button {
  flex: 1;
  text-align: center;
}

.fadeIn {
  -webkit-animation: c .3s forwards;
  animation: c .3s forwards;
}

.weui-half-screen-dialog {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 75%;
  z-index: 5000;
  line-height: 1.4;
  background-color: #fff;
  border-top-left-radius: 12px;
  border-top-right-radius: 12px;
  overflow: hidden;
  padding: 0 24px;
  padding: 0 calc(24px + constant(safe-area-inset-right)) constant(safe-area-inset-bottom) calc(24px + constant(safe-area-inset-left));
  padding: 0 calc(24px + env(safe-area-inset-right)) env(safe-area-inset-bottom) calc(24px + env(safe-area-inset-left));
}

.weui-half-screen-dialog__hd {
  font-size: 8px;
  height: 8em;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center;
}

.weui-half-screen-dialog__hd .weui-icon-btn {
  position: absolute;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

.weui-half-screen-dialog__hd__side {
  position: relative;
  left: -8px;
}

.weui-half-screen-dialog__hd__main {
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1;
}

.weui-half-screen-dialog__title {
  display: block;
  color: rgba(0, 0, 0, .9);
  font-weight: 700;
  font-size: 15px;
}

.weui-half-screen-dialog__hd__side+.weui-half-screen-dialog__hd__main {
  text-align: center;
  padding: 0 40px;
}

.weui-half-screen-dialog__hd .weui-icon-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

.weui-icon-close-thin {
  mask-image: url(data:image/svg+xml,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M12.25%2010.693L6.057%204.5%205%205.557l6.193%206.193L5%2017.943%206.057%2019l6.193-6.193L18.443%2019l1.057-1.057-6.193-6.193L19.5%205.557%2018.443%204.5z%22%20fill-rule%3D%22evenodd%22%2F%3E%3C%2Fsvg%3E);
  display: inline-block;
  vertical-align: middle;
  width: 24px;
  height: 24px;
  mask-position: 50% 50%;
  mask-repeat: no-repeat;
  mask-size: 100%;
  background-color: currentColor;
}

.weui-half-screen-dialog__bd {
  padding-top: 4px;
  padding-bottom: 40px;
  font-size: 14px;
  overflow-y: auto;
}

/* 蒙版 */
.mask {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: black;
  opacity: 0.5;
}
</style> 